import 'package:cunyutech_flutter_core/cunyutech_flutter_core.dart' hide FutureCallbackFunction;
import 'package:cunyutech_flutter_ui/src/application/main.dart';
import 'package:flutter/material.dart' hide Action;
import 'package:flutter/services.dart';
import 'package:flutter_dva/flutter_dva.dart';

import 'ApplicationInfo.dart';

class CYApplication {

  static void _zoomImageHotfix() {
    const maxBytes = 1024 * (1 << 20);
    SystemChannels.skia.invokeMethod('setResourceCacheMaxBytes', maxBytes);
  }

  static CYLogger logger = CYLogger(tag: "application");

  static ApplicationInfo info = ApplicationInfo();

  static Future initApp({
    bool isDev = false
  }) async {
    WidgetsFlutterBinding.ensureInitialized();
    CYLogger.isDev = isDev;
    ErrorWidget.builder = (FlutterErrorDetails details) {
      logger.error('[ErrorWidget]${details.toString()}');
      return Container();
    };
    _zoomImageHotfix();

    await Future.wait([
      /// 强制竖屏
      SystemChrome.setPreferredOrientations([
        DeviceOrientation.portraitUp,
        DeviceOrientation.portraitDown
      ]),
      /// 初始化系统信息
      info.init()
    ]);
  }

  static Future run({
    String bootstrap = "system/bootstrap",
    @required FutureCallbackFunction onPersisted,
    bool waitCallabck = true,
    @required WidgetCreatorFunction widgetCreator,
    @required List<Model> models,
  }) async {
    CYLogger logger = CYLogger(tag: "main");
    Dva dva = Dva(
      DvaOpts(
        initialState: <String, StoreOfState<StateTmpl>>{},
        models: models..add(CYApplicationModel()),
        onError: (dynamic error, Map<String,dynamic> context) {
          logger.error('[onError]${context["action"].type}');
          logger.error('[onError]$error');
        },
        onAction: (Action action) {
          logger.info('[onAction]${action.type}\t\t${action.payload}');
        }
      )
    );
    /// 注入 dva loading 插件
    dva.use(createLoading());

    WidgetCreatorFunction app = await dva.start(widgetCreator, () async {
      ReduxPersistor persistor = new ReduxPersistor(store: dva.store, heartBeat: 1500);
      /// 持久化数据
      await persistor.persist();
      /// 初始化数据库和配置
      if(onPersisted != null) await onPersisted();
      // 持久化完成后通知，跳转页面
      await dva.store.dispatch(Action(bootstrap, {}));
      // 持久化完成后，更新应用信息
      await dva.store.dispatch(Action("cyapplication/bootstrap", {}));
    }, waitCallabck: true);
    try {
      runApp(app());
    }
    on NetworkImageLoadException catch(ex) {
      logger.error(ex.toString());
    }
    catch (e) {
      logger.error(e);
    }
  }
}